#include <QtNetwork/QtNetwork>
#include <QtNetwork/QTcpSocket>
#include "depositdataaccess.h"
#include "common/dynobjectfactory.h"
#include "common/jinstream.h"
#include "control/bankexception.h"

#define DEPOSIT 0x03
#define BUF_SIZE    1024

DepositDataAccess::DepositDataAccess()
{
    data_ = new char[BUF_SIZE];
}

DepositDataAccess::~DepositDataAccess()
{
    delete []data_;
}

//数据进行请求发送
bool DepositDataAccess::requestData(QSharedPointer<QTcpSocket> &cliPipe,
                                    map<QString, QString> &rDataMap)
{
    quint16 cmd = DEPOSIT;
    jos_.Clear();
    jos_ << cmd;
    // 预留两个字节包头len(包体+包尾长度)
    quint64 lengthPos = jos_.Length();
    jos_.Skip(2);
    map<QString,QString>::const_iterator it;
    //帐号
    it = rDataMap.find("id");
    if(it == rDataMap.end()) {
        rDataMap.insert(make_pair("errorMsg",
            "Attribute Id can't be found!"));
        return false;
    }
    const char *pAccountId = it->second.toLocal8Bit();
    jos_.WriteBytes((quint8 *)pAccountId,it->second.length());
    // 金额
    it = rDataMap.find("cash");
    if(it == rDataMap.end()) {
        rDataMap.insert(make_pair("errorMsg",
            "Attribute Cash can't be found!"));
        return false;
    }
    jos_ << it->second.toStdString();
    // 包头len字段
    quint64 tailPos = jos_.Length();
    jos_.Reposition(lengthPos);
    jos_ << (quint16)(tailPos + 8 - sizeof(RequestHead));
    // 包尾
    jos_.Reposition(tailPos);
    generatePackTailMd5(cmd);
    cliPipe->write(jos_.Data(), jos_.Length());
    if(!cliPipe->waitForBytesWritten(3000)) {
        throw BankException(cliPipe->errorString().toLocal8Bit());
    }
    return true;
}

//对数据进行响应
bool DepositDataAccess::responseData(QSharedPointer<QTcpSocket> &cliPipe,
                                        map<QString, QString> &rDataMap)
{
    memset(data_,0,BUF_SIZE);
    if(!cliPipe->waitForReadyRead(3000)) {
        throw BankException(cliPipe->errorString().toLocal8Bit());
    }
    dataLen_ = cliPipe->read(data_,BUF_SIZE);
    //这里应该执行接收包的包验证
    if(!checkData()) {
        throw BankException("data check sum error!");
    }
    JInStream jis((const char*)data_, dataLen_);
    // 跳过cmd、len
    jis.Skip(4);
    uint16 cnt;
    uint16 seq;
    int16 error_code;
    jis >> cnt >> seq >> error_code;

    char error_msg[31];
    memset(error_msg,0,sizeof(error_msg));
    jis.ReadBytes(error_msg, 30);
    if(0 != error_code) {
        rDataMap.insert(make_pair("errorMsg",
                                error_msg));
        return false;
    }
    string name,money;
    jis >> name;
    jis >> money;
    char transDate[20] = {0};
    memset(transDate,0,sizeof(transDate));
    jis.ReadBytes(transDate,sizeof(transDate) - 1);
    rDataMap.insert(make_pair("resName",name.c_str()));
    rDataMap.insert(make_pair("resBalance",money.c_str()));
    rDataMap.insert(make_pair("resTransDate",transDate));
    return true;
}

REGISTER_CLASS(DepositDataAccess);
